package main

import (
	"fmt"
)

/*
panic
停止当前函数执行
一直向上返回,执行每一层的defer
如果没有遇见recover,程序退出

recover
仅在defer调用中使用
获取panic的值
如果无法处理,可以重新panic
*/
func tryRecover() {
	//recover 仅在defer中调用
	//匿名函数 defer func() {}() 注:defer func() {}定义匿名函数, ()表示调用该函数
	defer func() {
		//定义recover
		r := recover()
		//不需要执行recover
		if r == nil {
			fmt.Println("Nothing to recover. " +
				"Please try uncomment errors " +
				"below.")
			return
		}
		//如果获取到的返回值是error类型,打印error
		if err, ok := r.(error); ok {
			fmt.Println("Error occurred:", err)
		} else {
			//不确定的类型,重新panic
			panic(fmt.Sprintf(
				"I don't know what to do: %v", r))
		}
	}()

	// Uncomment each block to see different panic
	// scenarios.
	// Normal error
	//panic(errors.New("this is an error"))

	// Division by zero
	//b := 0
	//a := 5 / b
	//fmt.Println(a)

	//触发重新panic, 因panic接收的是interface{}, 任意类型
	// Causes re-panic
	panic(123)
}

func main() {
	tryRecover()
}
